package com.trade.core.trade;

import com.trade.core.context.TradeContextHandler;
import com.trade.core.exception.TradeBaseException;
import com.trade.core.message.TradeObjectRestResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
import com.trade.core.utils.BeanMapUtil;
import com.trade.core.utils.CollectionUtils;
import com.trade.core.utils.TradeCommonUtils;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author sven.wang
 * @version 2021/12/7 16:19
 * @Description: 交易构造器(核心组件)
 */
@Slf4j
public class TradeBuild {
    /**
     * 交易执行步骤
     */
    public List<ITradeProcessorStep> tradeProcessorSteps;

    public TradeBuild(List<ITradeProcessorStep> tradeProcessorSteps){
        this.tradeProcessorSteps = tradeProcessorSteps;
    }

    /**
     * 根据交易步骤，执行交易
     *
     * @param processStep 执行步骤枚举
     * @param tradeName   交易名(用于错误日志记录)
     * @param params 交易入参
     */
    public TradeObjectRestResponse processTradeBySteps(String[] processStep, String tradeName, Object params) {
        AtomicInteger i = new AtomicInteger();
        if(CollectionUtils.isEmpty(tradeProcessorSteps)){
            TradeContextHandler.remove();
            return TradeObjectRestResponse.error("trade processor is not exists");
        }
        //遍历需要执行的步骤
        for (String step : processStep) {
            try {
                i.getAndIncrement();
            //如果执行器步骤与需要执行的步骤一致,则执行
            Optional<ITradeProcessorStep> filterStep = tradeProcessorSteps.stream().filter(originStep -> originStep.step().equals(step)).findFirst();
            if(!filterStep.isPresent()){
                TradeContextHandler.remove();
                return TradeObjectRestResponse.error("trade process mismatch");
            }
            //如果是第一步
            if(i.get()==1 && params != null){
                //将入参设置入上下文
                TradeContextHandler.putAll((Map<String, Object>) BeanMapUtil.beanToMap(params));
            }
            //执行步骤内容
            TradeObjectRestResponse response = filterStep.get().process();
            //步骤处理失败直接响应失败返回
            if(!TradeCommonUtils.isSuccess(response)){
                log.error("trade process failed, failed message:[{}]",response.getMessage());
                TradeContextHandler.remove();
                return response;
            }
            //如果是最后一个
            if(i.get()==processStep.length){
                TradeContextHandler.remove();
                return response;
            }
            } catch (TradeBaseException baseException) {
                log.error("trade process error,trade name :{}, error step :{}, error message :{}", tradeName, step, baseException.getMessage(), baseException);
                TradeContextHandler.remove();
                throw new TradeBaseException(baseException.getMessage(), baseException.getStatus());
            } catch (Exception e) {
                log.error("trade process error,trade name :{}, error step :{},  error message :{}", tradeName, step, e.getMessage(), e);
                TradeContextHandler.remove();
                throw new TradeBaseException(e.getMessage());
            }
        }
        TradeContextHandler.remove();
        return TradeObjectRestResponse.error("trade process mismatch");
    }
}
